
VOLUME 50

DESCRIPTION:	Bob Van Valzah's "Pascal Pascal Compiler"
		and SPEED for CP/M 2.2 & a few miscellaneous
		programs for printing via UNIX.

NUMBER	SIZE	NAME		COMMENTS

		-CATALOG.050	CONTENTS OF CP/M VOL. 50
50.1	1K	A.OCO		Sample program, eight queens
				problem, ready to be
				linked to RTP.COM (OCO=obj code)
50.2	1K	A.PCO		Sample program P-code, ready
				for PFET.COM		
50.3	5K	ABSTRACT.050	Abstracts for this volume.
50.4	2K	COMPARE.COM	Vital program for
				compiler writers.
50.5	2K	CPMDIR.C	Prints CP/M DIR on UNIX.
50.6	2K	CRCK.COM	CRC program for validating
				files on this disk.
50.7	2K	CRCKLIST.CRC	CRC list of files on this disk.
50.8	3K	DISK.DOC	Bob's comments.
50.9	1K	DMSPATCH.ASM	For use with SPEED.
50.10	1K	DSCUSPAT.ASM	For use with SPEED.
50.11	3K	EQ.COM		Prints all solutions to the
50.12	2K	EQ.PAS		   eight queens problem.
50.13	18K	FMAN.PRN	FAST users manual (for SPEED).
50.14	5K	FROMCPM.C	Print CP/M file via UNIX stdout.
50.15	1K	FWD.PAS		Forward Procedure Declarations.
50.16	6K	HW5.COM		Builds optimal binary search
50.17	15K	HW5.PAS		   tree & decodes a message.
50.18	1K	HW5DATA.	Sample data for above program.
50.19	1K	MICROPAT.ASM	For use with SPEED.
50.20	6K	PASYNTAX.DOC	Syntax graphs for PPC compiler.
50.21	1K	PC.SUB		Submit file to compile a PPC
				   program.
50.22	7K	PFET.COM	Object code of Pcode to 8080
				   translator.
50.23	11K	PFET.PAS	Source of above.
50.24	1K	PHONE.C		C program to print words you
				   can spell with your phone #.
50.25	1K	PLAYDATA.	Sample data for above program.
50.26	13K	PLAYKAL.PAS	PPC program to determine best
				   moves in game of Kalah.
50.27	2K	POPS.DOC	DOC for Pcodes used by PPC.
50.28	1K	POWTWO.PAS	PPC Program to print negative
				   powers of two.
50.29	16K	PPC.COM		Pascal Pascal Compiler.
50.30	10K	PPC.DOC		DOC for above file.
50.31	26K	PPC.PAS		Pascal source for above file.
50.32	2K	PSTACK.DOC	DOC on run-time P-machine stack.
50.33	3K	REGEN.DOC	Notes on how to modify & compile
				   PPC.PAS.
50.34	3K	RSPEED.ASM	For use with SPEED.
50.35	1K	RSPEED.COM	For use with SPEED.
50.36	11K	RTP.ASM		Source for run-time package.
50.37	2K	RTP.COM		Object of above.
50.38	1K	SKEW2PAT.ASM	For use with SPEED.
50.39	1K	SKEW3PAT.ASM	For use with SPEED.
50.40	2K	SMAN.PRN	SPEED users manual.
50.41	5K	SPEED.COM	SPEED for CP/M 1.4
50.42	5K	SPEED2.COM	SPEED for CP/M 2.2
50.43	1K	STIRLING.PAS	Prints a table of Stirling
				   Numbers.
50.44	4K	TESTER.PAS	Tests functionality of PPC.
50.45	1K	VALIDATE.SUB	Submit file to make sure you
				   have a "fertile" computer.

---------------- VOLUME 50 ABSTRACTS ----------------

This file contains abstracts on the following programs
and files, most of which were submitted to the Users'
Group by Bob Van Valzah:

	A.OCO
	A.PCO
	COMPARE.COM
	CPMDIR.C
	DISK.DOC
	DMSPATCH.ASM
	DSCUSPAT.ASM
	EQ.COM
	EQ.PAS
	FMAN.PRN
	FROMCPM.C
	FWD.PAS
	HW5.COM
	HW5.PAS
	HW5DATA.
	MICROPAT.ASM
	PASYNTAX.DOC
	PC.SUB
	PFET.COM
	PFET.PAS
	PHONE.C
	PLAYDATA.
	PLAYKAL.PAS
	POPS.DOC
	POWTWO.PAS
	PPC.COM
	PPC.DOC
	PPC.PAS
	PSTACK.DOC
	REGEN.DOC
	RSPEED.ASM
	RSPEED.COM
	RTP.ASM
	RTP.COM
	SKEW2PAT.ASM
	SKEW3PAT.ASM
	SMAN.PRN
	SPEED.COM
	SPEED2.COM
	STIRLING.PAS
	TESTER.PAS
	VALIDATE.SUB


====> PPC.COM, PFET.COM and related files comprise
Bob Van Valsah's Pascal compiler.  It is a compiler
for a subset of the Pascal programming language, written
in Pascal and can compile itself.
     The sample programs that I compiled worked as they
should.  The Eight Queens program (EQ.PAS) printed a bunch of
permutations of the digits 1 to 8 tho I didn't get out
my chess board and check them.
     POWTWO.PAS prints the negative powers of two from .5 to
.0009765625 (2**-1...2**-10).
     Both programs took less than half a minute to compile using the
supplied SUBMIT file and SPEED2.COM (bet you thought no one
used SUBMIT files!).  EQ.COM took less than half a minute to run
and POWTWO.COM ran as fast as it could print.  This was done on
a 2 meg Z-80.  When they were compiled without SPEED2.COM they both
took more than a minute.
     The compiler was a class assignment for one of Bob's
classes.  It is very well documented as to how to use the
compiler and the specific subset it compiles (it even has
some of Bob's usual creative misspellings).
     Those interested in the innards of compilers or large
programs in general should find this interesting.
     Abstract by Paul Krystosek


Contents of this disk -- largely from DISK.DOC notes by Bob Van Valzah
=====================

	A.OCO -- This sample program is the object code output of
the PFET portion of the compiler package.  (OCO = Object COde).

	A.PCO -- This sample program is the P-code output of
the PPC.COM portion of the compiler.  Both A.PCO and A.OCO,
in this case, are partially compiled outputs of EQ.PAS, the
eight queens problem.  Normally, if you use the PC.SUB file
for compilations, A.OCO and A.PCO will both be written to disk
and subsequently erased by the submit file.

	COMPARE.COM -- program to compare two files, from
CP/M Users' Group disk #40, useful for checking differences
between different versions of the same program.

	CPMDIR.C -- A UNIX C program for printing a CP/M
directory to STDOUT (UNIX printer).

	DISK.DOC -- Bob Van Valzah's notes on some of the
files on this disk.

	DMSPATCH.ASM -- Patching for SPEED.COM or SPEED2.COM
for use on DMS controller.

	DSCUSPAT.ASM -- Patching for SPEED.COM or SPEED2.COM
for use on the DISCUS controller.

	EQ.COM -- Compiled output of EQ.PAS, the eight queens
chess problem, written by Bob.

	EQ.PAS -- Source code in Pascal to print out all solutions
to the eight-queens chess problem.

	FMAN.PRN -- "Fast Manual" -- documentation for SPEED.

	FROMCPM.C -- UNIX C program to print a CP/M file to STDOUT
via modem.

	FWD.PAS -- Sample Pascal Program.

	HW5.COM -- Sample program.

	HW5.PAS -- Sample PASCAL program to build an optimal search
tree and decode a message.

	HW5DATA. -- Sample data for above program.

	MICROPAT.ASM -- Patch for SPEED for use on MICROPOLIS disk
controller systems.

	PASYNTAX.DOC -- Bob's notes on PASCAL syntax.

	PC.SUB -- Submit file for compiling from .PAS file to .COM file.

	PFET.COM -- Part of PPC compiler package.

	PFET.PAS -- Source code for the PFET portion of the compiler
package (compiles P-code into object code).

	PHONE.C -- UNIX C program to print out the words you can spell
with your phone number.

	PLAYDATA. -- data for following program.

	PLAYKAL.PAS -- Sample program to determine best moves in a game
of Kalah (Anybody know how to play Kalah?)

	POPS.DOC -- Bob's documentation on the P-codes used by the
compiler.

	POWTWO.PAS -- Sample program to print out the negative powers of 2.

	PPC.COM -- PASCAL PASCAL COMPILER.

	PPC.DOC -- Documentation on the compiler.

	PPC.PAS -- Pascal Source code for the compiler.

	PSTACK.DOC -- Documentation on the stack operations of the
run-time P-machine.

	REGEN.DOC -- Notes on how to modify and recompile the compiler.

	RSPEED.ASM -- Disk Hardware Read Speed Tester.

	RSPEED.COM -- Object of above.

	RTP.ASM -- Run Time Package Source code file.

	RTP.COM -- Run Time Package Object code file.

	SKEW2PAT.ASM -- Patch for SPEED or SPEED2.

	SKEW3PAT.ASM -- Patch for SPEED or SPEED2.

	SMAN.PRN -- Speed Users Manual.

	SPEED.COM -- Disk Speed-up program for CP/M 1.4

	SPEED2.COM -- Same as above for CP/M 2.2

	STIRLING.PAS -- Sample program to generate Stirling numbers.

	TESTER.PAS -- Sample program.

	VALIDATE.SUB -- Submit file to verify that your computer is "fertile."





Contents of this disk
=====================


compare.com	file compare utility from previous CP/M UG disk
		an absolute must for self compiler writers

cpmdir.c	V7 UNIX C program to print a CP/M directory on stdout

disk.doc	this file

eq.pas		prints all solutions to the "eight queens problem"

fromcpm.c	V7 UNIX C program to read a CP/M file to standard output

fwd.pas		Pascal program illustrating forward procedure declarations

hw5.pas		builds an optimal binary search tree and decodes a message

hw5data		sample data for above

pasyntax.doc	syntax graphs for this Pascal compiler

pc.sub		submit file to compile a Pascal program

pfet.com	object code of the p-code to 8080 translator

pfet.pas	source of above

phone.c		C program to print words you can spell with your phone number

playkal.pas	Pascal program to determine best moves in game of Kalah

playdata	sample data for above

pops.doc	documentation on the p-codes used by the compiler

powtwo.pas	Pascal program to print negative powers of two

ppc.com		object code of Pascal to p-code compiler

ppc.doc		users manual for Pascal compiler

ppc.pas		source of Pascal compiler

pstack.doc	documentation on the run time p-machine stack

regen.doc	notes on how to modify and compile the compiler

rtp.asm		source for the run time package

rtp.com		object of above

speed.com	makes your system go faster by disk buffering

speed2.com	above for 2.x systems

stirling.pas	Pascal program to print a table of Stirling numbers

tester.pas	tests functionality of Pascal compiler

validate.sub	submit file to make sure you have a "fertile" compiler



Both playkal.pas and hw5.pas are solutions to programming assignments
for my computer science classes at the University of Illinos.  They are
included here to show how to build trees when you don't have pointers.
They also illustrate a kludgey way of simulating Pascal records when you
don't have them either.

stirling.pas is included to show a kludgey way to do output formatting.


UPPER CASE means that this reserved word must appear literaly.



identifier
------------> letter ------------------------>
			^	      |
			|-- letter <--|
			|-- digit  <--|


number
------------> digit -------->
	^	        |
	|---------------|


constant
-----------> number ---------------------------------------------->
	|						     ^
	|--> constant identifier ----------------------------|
	|			   ^			  |  |
	|			   |-- constant <--  +  --|  |
	|						     |
	|						     |
	|-->  '  --> character -->  '  ----------------------|


simple type
----------------> type identifier ---------------->
	|				       ^
	|-->  (  ----> identifier ----->  )  --|
	|	   ^		    |	       |
	|	   |------  ,  <----|	       |
	|				       |
	|--> constant -->  ..  --> constant ---|


type
----------------> simple type -------------------------------->
	|						^
	|--> ARRAY -->  [  --> simple type -->  ] --|   |
						    |   |
	   |----------------------------------------|   |
	   |						|
	   |--> OF --> simple type ---------------------|


variable
------------> variable identifier ---------------------------->
				    |	  |
	|---------------------------|	  |
	|				  |
	|-->  [  --> expression -->  ]  --|


factor
------------>  '  -----> character ----->  '  ---------------->
	|	    ^		     |			|
	|	    |----------------|			|
	|						|
	|--> variable --------------------------------->|
	|						|
	|--> function identifier ---------------------->|
	|			   |			|
	|  |-----------------------|			|
	|  |						|
	|  |-->  (  -----> expression ----->  )  ------>|
	|	      ^			|		|
	|	      |-----  ,  <------|		|
	|						|
	|-->  (  --> expression -->  )  --------------->|
	|						|
	|--> constant ----------------------------------|


term
------------> factor -------------------------------->
	^			 |
	|-- factor <-----  *  <--|
		      ^		 |
		      |--  /  <--|
		      |-- AND <--|

simple expression
----------->  +  -------> term -------------------------------->
	|	   ^ ^			    |
	|-->  -  --| |-- term <-----  +  <--|
				 ^	    |
				 |--  -  <--|
				 |--  OR <--|


expression
-----------> simple expression -------------------------------------->
				|				    ^
				|-->  =  -----> simple expression --|
				|	   ^
				|-->  <  --|
				|-->  >  --|
				|-->  <> --|
				|-->  <= --|
				|-->  >= --|


parameter list
-------------------------------------------------------------------------->
 |								  |
 |--> ( -----> identifier -----> : --> type identifier -----> ) --|
	 ^ ^		    |				 |
	 | |-----  ,  <-----|				 |
	 |						 |
	 |-----------------------  ;  <------------------|



statement
--------------------------------------------------------------------->
 |								  ^
 |-----> variable ---------------->  :=  --> expression --------->|
 |  |			       ^				  |
 |  |--> function identifier --|				  |
 |								  |
 |--> procedure identifier -------------------------------------->|
 |			     |					  |
 |  |<-----------------------|					  |
 |  |								  |
 |  |-->  (  ------------------> expression ----->  )  ---------->|
 |	       |	  ^ ^		      |			  |
 |	       |--> VAR --| |------  ,  <-----|			  |
 |								  |
 |--> BEGIN -----> statement -----> END ------------------------->|
 |	      ^		       |				  |
 |	      |-----  ;  <-----|				  |
 |								  |
 |--> IF --> expression --> THEN --> statement ------------------>|
 |					         |		  |
 |				       |<--------|		  |
 |				       |			  |
 |				       |--> ELSE --> statement -->|
 |								  |
 |--> CASE --> expression --> OF ------------------------> END -->|
 |				   |		      ^		  |
 |  |<-----------------------------|		      |		  |
 |  |					  	      |		  |
 |  |-----> constant --> : --> statement ------------>|		  |
 |     ^				   | |	      |		  |
 |     |---------------  ;  ---------------| |        |		  |
 |					     |        |		  |
 |		|<---------------------------|        |		  |
 |		|				      |		  |
 |		|--> ELSE --> statement ------------->|		  |
 |								  |
 |--> WHILE --> expression --> DO --> statement ----------------->|
 |								  |
 |--> REPEAT -----> statement -----> UNTIL --> expression ------->|
 |	       ^		|				  |
 |	       |-----  ;  <-----|				  |
 |								  |
 |--> GET -->  #  --> constant -->  (  --> variable -->  )  ----->|
 |								  |
 |--> PUT -->  #  --> constant -->  (  --|			  |
 |					 |			  |
 |		   |<--------------------|			  |
 |		   |						  |
 |		   |-----> expression ------------------->  )  -->|
 |		      ^			|	   ^  |		  |
 |		      |			|-->  #  --|  |		  |
 |		      |				      |		  |
 |		      |----------  ,  <---------------|		  |
 |								  |
 |--> FOR --> variable identifier -->  :=  --> expression --|	  |
							    |	  |
	 |<-------------------------------------------------|	  |
	 |							  |
	 |-----> DOWNTO -----> expression --> DO --> statement -->|
	    |		  ^
	    |----> TO ----|


block
-----------> CONST -----> identifier -->  =  --> constant --|
	|	     ^					    |
	|	     |					    |
	|<-------------------------------------  ;  <-------|
	|
	|--> TYPE ------> identifier -->  =  --> type ------|
	|	     ^					    |
	|	     |					    |
	|<-------------------------------------  ;  <-------|
	|
	|--> VAR -------> identifier ----->  :  --> type identifier ---|
	|	     ^		       |		               |
	|	     |<-----  ,  ------|		    	       |
	|	     ^					    	       |
	|<-------------------------------------------------------------|
	|
	|<-----  ;  <----- block <-----  ;  <--------------------|
	|							 |
	|-----> procedure -----> identifier --> parameter list --|
	|  |		    ^
	|  |--> function ---|
	|
	|--> begin -----> statement -----> end -------------------->
		     ^		      |
		     |-----  ;  <-----|


program
------------> block -->  .  ---------------------------------------->


This file descibes the function of each of the p-op codes, as best I
can remember them while looking at my notes and code of over a year
ago.  (Sorry, it's the best I can offer you.)

Entered 02/20/81, from notes dated 09/01/79

The compiler does not generate all of the p-codes given here.  Some
were for planed enhancements that never were finished.  Similarlay,
the translator (pfet) will translate many p-codes that the compiler
presently does not generate.  There may be some p-codes it does
generate that are not listed here, but this is the bulk of the
usefull ones and will give you the general idea.



lit	0,c	push word constant c into stack

opr	n,m	perform operation m on top of stack
		element(s) of type n, where n=0 is word, n=1 is alfa

lod	l,a	push word at l+a into stack

sto	l,a	po stack into l+a

cal	l,a	call routine at p label a, level l away

int	0,n	add n to stack pointer

jump	0,a	jump to p label a

jpc	c,a	jump to p label a after popping stack
		c=0 jump if (top)=false, c=1 jump if (top)=true

csp	0,n	call standard procedure n

lodx	l,a	push word at l+a+(top) into stack

stox	l,a	pop stack into l+a+(top-1)

alit	0,0	push alfa which follows (next 2 p-ops or 8 bytes)
		into stack, msbyte follows first (may have changed)

alod	l,a	push alfa at l+a into stack

asto	l,a	pop alfa from stack into l+a

alodx	l,a	push alfa at l+a+(top) to stack

astox	l,a	pop alfa from stack into l+a+(top-5)

pshf	0,0	push true or false into stack based on result
		of last conditional executed

laa	l,a	load absolute machine address of l,a into stack
		used for var parameters

lodi	0,0	load word pointed to by top of stack into stack
		pops address first

stoi	0,0	store word on top of stack at address on (top-1)

lab	0,n	defines the p label n

			PPC Users Manual

How to use the compiler
=======================

If you have a file named dog.pas and you want to compile it, you'd
just type

	submit pc dog

The compiler will ask "LISTING?".  You reply with a single character;
carriage return means no listing, any other character means yes listing.
The listing will be sent to the console as the compilation proceeds.
Any errors detected in the compilation are flagged in this listing.
At some point (hopefully reasonably near to the point of infraction)
the error number will be inserted into the listing, enclosed in ">>"
and "<<".  The line following an error will start with "********"
and otherwise be blank to call attention to the error.  The compiler
will also wait for a single character from the console before
compilation continues.  This is so people with crt's can see the
error.  Error numbers should be looked up in Jensen and Wirth (see
below).  Error number 99 is pound sign ("#") expected.

The compiler should work with a 32k CP/M and might work in 24k, but
there are no memory overflow checks.  If it hangs or something, you
probably don't have enough memory.

On good sized programs, the compiler manages to get about 300-400
lines of Pascal translated to object per minute.  These figures were
taken on my system with 2mHz Z-80, 8" disk, running under SPEED.
Compilation speed will fall to less than half this rate without SPEED,
thus SPEED is strongly recommended.  This is particularly true if
you use the submit file to do the compilation.  The run time package
does only single sector disk buffering and this too makes SPEED
very important.

How it all works
================
The program PPC.COM takes your Pascal source and makes a single pass
over it translating it to a sort of p-code as it goes.  This p-code is
written to disk.  PFET.COM reads the p-code file on its first pass,
assigning 8080 addresses to all p-code labels and storing the p-code
in memory for the second pass.  On its second pass, PFET reads the
p-code from memory and generates the actual 8080 object code.  This
code is written to a disk file.  The last step in compilation is to
link the generated object code to the run time package.  This is done
by simply using PIP to concatenate the run time package and the object
file from PFET to produce an executable .COM file.  The compiler (PPC)
is written in Pascal, as is the p-code translator (PFET).  The run time
package is written in assembler.



Differences from "standard" Pascal
==================================

This section will detail the ways in which ppc deviates from standard
Pascal as defined in "Pascal User Manual and Report", second ed., K.
Jensen and N. Wirth.


Two additional reserved words have been defined:  get and put.
The following words are not now considered reserved, but are
in standard Pascal, so they should be avoided:  file, goto, in, label,
nil, packed, set, and with.

The ASCII tab character is an acceptable white space character.

Comments are begun with the sequence "(*" and ended with "*)".

Identifiers may be very long, but only the first 8 are significant.


The data type Boolean is not supported.  Relational and logical
operators may be used only in if statements.  The boolean constant
identifiers true and false are not defined.  The not operator is
not implemented.  These are the legal relational and logical
operators:  =, <>, <, <=, >=, >, and, and or.

The data type integer is available.  Values must be in the range -32768 to
32767.  There are no standard functions such as abs, sqr, trunc, etc.
The constant maxint is not defined by the compiler.  The type integer is
identical to type word.  The following operations are defined on integers:

	*	multiply
	/	divide and truncate (why use div? int's are all you've got!)
	+	add
	-	subtract

Multiplication and division are presently implemented with repeated
addition and subtraction (gag!).  This makes the order of the operands
critical.  If one operand is likely to be less than the other, put the
lesser operand on the left of the multiplication symbol for best speed.
Dividing a large number by one takes a long time -- dividing it by zero
takes forever!  (It's not that I'm not aware of the shiftng methods
of division and multiplication, it's just that I wanted something quick
and didn't feel like looking up the good routines.  I've never felt
the need to replace these routines with the good ones.)

Also note that there is no integer negation.  If you want negative one,
write it as 0-1.

The type real is not supported.

The type char is not supported, but see type alfa below.

The type alfa can hold eight characterers.  Alfas can be assigned and
compared just like integers (just don't try to do math on them!).
All relational operators are defined using the ASCII collating sequence.
Length can't enter into the compariosn because alfas are always eight
characters long (it's up to you to supply padding).  Alfas may be passed
as parameters.


Since files are not supported, the program heading is not needed, and
in fact, is not allowed.  The first thing the compiler expects to see
are the global constant declarations.

Goto statements are not supported, therefore label declarations are not
needed and not permitted.

Constant declarations are pretty much the same as in regular Pascal,
except that leading signs are not allowed and character constants
can be only one character in length.  A minor extension is that I put
in limited compile time constant expressions to make coding the
translator easier.  See the syntax graphs to see where these can be
used.

Variable declarations have the restriction that the type must be
a type identifier and may not be a complex type.  Thus

	var months : array [ 1 .. 12 ] of integer;

is illegal, while

	type mtharray = array [ 1 .. 12 ] of integer;
	var  months : mtharray;

is legal.

In this implementation, functions can return only integer values.
This makes it unnecessary (and illegal) to give a function return type
in the function declaration.


The case statement is limited in that it cannot accept multiple case
labels on the same statement.  On the other hand, it has been extended
to allow an else statement which is executed when none of the case
labels match the expression value.  See the syntax graphs for the syntax.


Single dimensional arrays of integers and alfas (the two "built-in" types)
are allowed.  You can also declare arrays of subrange or enumerated types,
but these are treated as arrays of integers and take the same amount of
storage.  Of course, arrays of arrays are not allowed, as that would
be more than one dimension.

If a simple alfa variable appears with a subscript after it, it is
treated as though it were an array of integers.  This fact can be used
to get at the individual characters of an alfa variable.  For example,
if "a" is a simple (not an array) alfa variable, then a[0] refers to
the first two characters.  The least significant eight bits would
contain the first character and the most significant eight bits would
contain the second character.


Record types are not allowed.  Therefore, there is no need for a with
statement.


There is no set type.  (However, it shouldn't be too hard to implement
a 64-bit set type using the p-instructions already around for alfa
variables . . . ).


There are no pointer types, and consequently, no new function.


There are no files and no read or write statements.  All input and
output is done with the put and get statements.  These are only vaguely
similar to the standard Pascal put and get.  GET#0 gets one character
from the input file.  PUT#0 sends its output to the output file.  PUT#1
sends its output unconditionally to the console.  The arguments to the
put statements consist of a series of expressions separated by commas.
If an expression evaluates to an alfa, all eight characters of the alfa
are printed.  Integer expressions followed by a pound sign ('#') will
print the decimal value of the expression.  If no pound sign follows
the expression, the low eight bits of the expression are sent as one
character.  The input and output files mentioned above can be either
disk files or console input and output.  Which is used depends on what
is typed on the command line following the compiled .com file when it
is executed.  If the first filename following the .com file name is
blank or '*', then input characters are taken from the console.  If
it is the name of a disk file, then input comes from that disk file.
A similar rule applies to the second filename following the command
and the destiny of the output characters.


Var parameters are different in that if one parameter to a procedure
is to be var, then all parameters must be var parameters.  This is
a silly restriction that should be easily removed by any talented
compiler hacker.  There is a also a small kludge to make the compiler's
job easier;  the word var must appear in the call to all procedures
with var parameters, as well as in the declaration.  This is very
easy to forget an a real nuisance at times.  Somebody please fix.


It is possible to forward declare procedures an functions, but as
with var parameters, there is a minor syntactic kludge to make the
compiler's life easier.  The forward part is handled in the normal
way except that you D-O-N-'-T give the parameter list (the compiler
never checks procedure calls against their declarations anyway!).
When you actually want to declare the procedure, use the form

	procedure foo(<real parameter list>); backward;

This gives the compiler a hint it can't miss that this procedure
was forward declared earlier!



The runtime stack is kept on the 8080 machine stack.

In all diagrams below, the highest memory address is at the T-O-P
of the diagram.

		char		word		alfa (01234567)
		====		====		===============
						7
						6
						5
						4
						3
						2
				H		1
pointer to ->	x		L		0


	    ____________________
	 -5 | return address   |
	 -4 |__________________|
	 -3 | dynamic link     |
	 -2 |__________________|
	 -1 | static link      |
BR ->	  0 |__________________|
	  1 | local variable 1 |
	  2 |                  |
	  . |                  |
	  . |                  |
	  . | local variable n |
	  n |__________________|
	    | function value   |    function return value
	-10 |__________________|
	 -9 | parameter 1      |
	 -8 |__________________|
	 -7 | parameter 2      |
	 -6 |__________________|
	 -5 | return address   |
	 -4 |__________________|
	 -3 | dynamic link     |
	 -2 |__________________|
	 -1 | static link      |
BR ->	  0 |__________________|
	  1 | local variable 1 |
	  2 |__________________|
		
	^^^ offsets from BR (base register)



The runtime stack is kept on the 8080 machine stack.

In all diagrams below, the highest memory address is at the T-O-P
of the diagram.

		char		word		alfa (01234567)
		====		====		===============
						7
						6
						5
						4
						3
						2
				H		1
pointer to ->	x		L		0


	    ____________________
	 -5 | return address   |
	 -4 |__________________|
	 -3 | dynamic link     |
	 -2 |__________________|
	 -1 | static link      |
BR ->	  0 |__________________|
	  1 | local variable 1 |
	  2 |                  |
	  . |                  |
	  . |                  |
	  . | local variable n |
	  n |__________________|
	    | function value   |    function return value
	-10 |__________________|
	 -9 | parameter 1      |
	 -8 |__________________|
	 -7 | parameter 2      |
	 -6 |__________________|
	 -5 | return address   |
	 -4 |__________________|
	 -3 | dynamic link     |
	 -2 |__________________|
	 -1 | static link      |
BR ->	  0 |__________________|
	  1 | local variable 1 |
	  2 |__________________|
		
	^^^ offsets from BR (base register)



Notes on regenerating the compiler
==================================


When reassembling the runtime package, do not use LOAD to create RTP.COM.
Instead, you must use a debugger and do the following:

1) Assemble RTP.ASM to produce RTP.HEX.  Make note of the final code
   address printed by the assembler.  RTP.COM should go up to this
   address minus 1.

2) Fire up your favorite debugger (DDT will do).

3) Fill memory with 0's.  100h - 1000h should do.

4) Now you can read in RTP.HEX, starting at 100h.

5) Boot back to the CCP.

6) Save memory up to one byte below the final code address printed by
   the assembler.  F'rinstance if 0600 was last address, type
   "SAVE 5 RTP.COM".

This procedure must be followed so that PIP can be used to concatenate
the runtime package and the object code produced by the compiler.
It will also make your life a lot easier when using COMPARE.COM to
compare parents and childern (should you ever try and extend the compiler).


If you make changes to ppc.pas or pfet.pas, you'll want to be sure
that the new compiler is capable of compiling itself.  In genetics,
this would be like making sure that your children are not sterile.
The file validate.sub should help make sure you don't have sterile
children.  It uses a "know fertile" compiler (ppc.com, pfet.com) to
compile the new ppc.pas and pfet.pas.  The resulting compiler is then
used to compile ppc.pas and pfet.pas again.  The results of this
second compilaton are compared to the results of the first.  If they
match, it is safe to erase the "known fertile" compiler because you
now know that you have a compiler which can reproduce itself.  If
they miscompare, you'd better find out why and fix it before erasing
the parents.  You should also note that this test only guarantees
that you'll be able to continue to use the compiler to compile itself.
It does N-O-T guarantee that you've got a fully functional compiler,
because the compiling the compiler does not exercise all functions
of the compiler.

After making any changes to the compiler, you'll probably want to
make sure that you can still compile and execute tester.pas.  This
test doesn't test all functions of the compiler either, but passing
tester is good sign that you haven't broken anything major.  By the
way, it is normal to get a few type missmatch errors while compiling
tester.  A new version of the compiler which is smarter about type
checking would prevent these messages.
